//
//  WebController.swift
//  XPApp
//
//  Created by zhuxietong on 2017/2/19.
//  Copyright © 2017年 zhuxietong. All rights reserved.
//
import Foundation
import UIKit
import WebKit
import Eelay
////
//public class SoWebViewConfiguration:WKWebViewConfiguration,WKScriptMessageHandler {
//    
//    public var hander_block: SoJs_Hander_Block?
//    
//    public func userContentController(_ userContentController: WKUserContentController,didReceive message: WKScriptMessage) {
//        self.hander_block?(userContentController,message)
//    }
//    
//    public var config_block:SoJs_Config_Block
//    {
//        get{
//            return {_,_ in }
//        }
//        
//        set(newValue){
//            let userController:WKUserContentController = WKUserContentController()
//            newValue(userController, self)
//            self.userContentController = userController;
//        }
//    }
//    
//}


open class WebConfiguration:WKWebViewConfiguration,WKScriptMessageHandler {
    
    public var receiveJsAction:((_ message:WKScriptMessage,_ controller:WKUserContentController) ->Void) = {_,_ in}
    
    public var initBlock:((_ hander:WKScriptMessageHandler,_ user_controller:WKUserContentController)->Void)
    {
        get{
            return {_,_ in }
        }
        set(newValue){
            let userController:WKUserContentController = WKUserContentController()
            newValue(self,userController)
            self.userContentController = userController;
        }
    }
    
    public func userContentController(_ userContentController: WKUserContentController,didReceive message: WKScriptMessage) {
        receiveJsAction(message, userContentController)
    }
}





public struct Web {
    public static var TitleKeyPath = "title"
    public static var EstimatedProgressKeyPath = "estimatedProgress"
}


public struct JSAction {
    public var action:(String,NSMutableDictionary,UIViewController)->Void = {_,_,_ in}
    public init(_ action:@escaping ((_ actionID:String,_ model:NSMutableDictionary,_ controller:UIViewController)->Void)) {
        self.action = action
    }
}



public typealias JSObserver = (WKScriptMessage,UIViewController?) -> Bool

extension WebController
{
    public static var JSObservers = [JSObserver]()
    
    
    open func receiveJsAction(actionID:String,model:NSMutableDictionary)
    {
        let fullPath = model["fullPath",""]
        if fullPath.len > 0
        {
            let url = "http://192.168.0.125:8080" + fullPath
            let ctr = WebController(urlString: url)
            ctr.displaysHostTitle = false
            ctr.displaysWebViewTitle = false
            ctr.title = model["meta.title",""]
            navigationController?.pushViewController(ctr, animated: true)
        }
        //        for action in self.actions {
        //
        ////            action.action(actionID, model, self)
        //        }
    }
    
    
   
    
}

@objc open class WebController: TypeInitController{
    
    @objc public convenience init(urlString:String)
    {
        
        let url = URL(string: urlString)
        //        self.init(urlRequest: Foundation.URLRequest(url: url!), configuration: config, activities: nil)
        self.init(urlRequest: Foundation.URLRequest(url: url!))
        
    }
    open var jsconfig:WebConfiguration{
        get{
            let config = WebConfiguration()
            config.initBlock = { hander,controller in
                controller.add(hander, name: "callApp")
                
                let user = JoUser.loginUser()
                let token = user?.token ?? ""
                let userid = user?.userid ?? ""
                let appInfo =
                """
                function getAppInfo(){
                window.localStorage.setItem('client','iosapp')
                return {'token':'\(token)','userid':'\(userid)','client':'iosapp'}
                }
                """
                let script11 = WKUserScript(source: appInfo, injectionTime: WKUserScriptInjectionTime.atDocumentStart, forMainFrameOnly: true)
                let script12 = WKUserScript(source: appInfo, injectionTime: WKUserScriptInjectionTime.atDocumentEnd, forMainFrameOnly: true)
                controller.addUserScript(script11)
                controller.addUserScript(script12)
            }
            
            
            weak var wself = self
            config.receiveJsAction = {
                message,controller in
                
                let observers = WebController.JSObservers
                for one  in observers {
                    _ = one(message,wself)
                }
                
            }
            return config
        }
    }
    
    // MARK: Properties
    open var loadImmediately:Bool{
        return true
    }
    
    public static var tinyColor = UIColor.darkGray
    
    /// Returns the progress view for the controller.
    public final var progressBar: UIProgressView {
        get {
            return _progressBar
        }
    }
    
    /// The URL request for the web view. Upon setting this property, the web view immediately begins loading the request.
    public final var urlRequest: Foundation.URLRequest {
        didSet {
            //            webView.load(urlRequest)
        }
    }
    
    /**
     Specifies whether or not to display the web view title as the navigation bar title.
     The default is `false`, which sets the navigation bar title to the URL host name of the URL request.
     */
    public final var displaysWebViewTitle: Bool = true
    public final var displaysHostTitle: Bool = false
    
    public final var displayShareButton: Bool = false
    
    
    //    public var webView:WKWebView!
    
    
    open var webView: WKWebView {
        get{
            // FIXME: prevent Swift bug, lazy property initialized twice from `init(coder:)`
            // return existing webView if webView already added
            let views = self.webContainerView.subviews.filter {$0 is WKWebView } as! [WKWebView]
            if views.count != 0 {
                return views.first!
            }
            
            view.backgroundColor = .white
            
            let info = self.jsconfig
            
            let webView = WKWebView(frame: .zero, configuration: info)
            
            self.layWebView(webView: webView)
            
            webView.addObserver(self, forKeyPath: Web.TitleKeyPath, options: .new, context: nil)
            webView.addObserver(self, forKeyPath: Web.EstimatedProgressKeyPath, options: .new, context: nil)
            webView.allowsBackForwardNavigationGestures = true
            webView.uiDelegate = self
            webView.navigationDelegate = self
            return webView
        }
    }
    
    open func layWebView(webView:WKWebView) {
        self.webContainerView.addSubview(webView)
        webView.autoresizingMask = [.flexibleHeight, .flexibleWidth]
    }
    
    open var webContainerView:UIView{
        return self.jo_contentView
    }
    
    open func receiveJs(message:WKScriptMessage,controller:UIViewController?){
        
        
    }
    
    fileprivate lazy final var _progressBar: UIProgressView = { [unowned self] in
        let progressBar = WebProgressView(progressViewStyle: .bar)
        progressBar.backgroundColor = .clear
        progressBar.trackTintColor = .clear
        progressBar.progressTintColor = UIColor._tint.alpha(0.5)
        progressBar.alpha = 0
        
        self.view.addSubview(progressBar)
        return progressBar
        }()
    
    
    fileprivate final let activities: [UIActivity]?
    
    public init(urlRequest: Foundation.URLRequest, configuration: WKWebViewConfiguration = WKWebViewConfiguration(), activities: [UIActivity]? = nil) {
        self.urlRequest = urlRequest
        self.activities = activities
        super.init()
    }
    
    /**
     Constructs a new `WebViewController`.
     
     - parameter url: The URL to display in the web view.
     
     - returns: A new `WebViewController` instance.
     */
    
    public init(url: URL,wk_config:WKWebViewConfiguration) {
        self.urlRequest = Foundation.URLRequest(url: url)
        self.activities = nil
        super.init()
    }
    
    public convenience init(url: URL) {
        self.init(urlRequest: Foundation.URLRequest(url: url))
    }
    
    public required init() {
        self.activities = nil
        self.urlRequest = Foundation.URLRequest(url: URL(string: "http:www.baidu.com")!)
        super.init()
    }
    
    /// :nodoc:
    public required init?(coder aDecoder: NSCoder) {
        self.urlRequest = Foundation.URLRequest(url: URL(string: "")!)
        self.activities = nil
        super.init(coder: aDecoder)
    }
    
    deinit {
        if webViewHaveObserver
        {
            webView.removeObserver(self, forKeyPath: Web.TitleKeyPath, context: nil)
            webView.removeObserver(self, forKeyPath: Web.EstimatedProgressKeyPath, context: nil)
        }
    }
    
    
    // MARK: View lifecycle
    
    /// :nodoc:
    fileprivate var webViewHaveObserver = false
    var backColor:UIColor? = nil
    open override func viewDidLoad() {
        super.viewDidLoad()
        
        // FIXME: prevent Swift bug, lazy property initialized twice from `init(coder:)`
        // return existing webView if webView already added
        
        
        
        view.backgroundColor = ._background
        //        webView = WKWebView(frame: .zero, configuration: self.configuration)
        self.layWebView(webView: webView)
        
        webView.addObserver(self, forKeyPath: Web.TitleKeyPath, options: .new, context: nil)
        webView.addObserver(self, forKeyPath: Web.EstimatedProgressKeyPath, options: .new, context: nil)
        webView.allowsBackForwardNavigationGestures = true
        //        webView.uiDelegate = self
        //        webView.navigationDelegate = self
        
        webViewHaveObserver = true
        if let bcolor = backColor{
            self.jo_contentView.backgroundColor = bcolor
            view.backgroundColor = bcolor
            webView.isOpaque = false
            webView.backgroundColor = bcolor
        }else{
            self.jo_contentView.backgroundColor = ._background
            view.backgroundColor = ._background
            webView.isOpaque = false
            webView.backgroundColor = ._background
        }
               
        if self.displaysHostTitle
        {
            title = urlRequest.url?.host
        }
        
        //        if presentingViewController?.presentedViewController != nil {
        //            navigationItem.leftBarButtonItem = UIBarButtonItem(
        //                barButtonSystemItem: .done,
        //                target: self,
        //                action: #selector(didTapDoneButton(_:)))
        //        }
        
        if self.displayShareButton{
            navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .action,target: self,action: #selector(didTapActionButton(_:)))
        }
        
        if loadImmediately
        {
            beginRequest()
        }
        let __title__ = mo.model["__title__",""]
        if __title__.len > 0{
            displaysHostTitle = false
            displaysWebViewTitle = false
            title = __title__
        }
        let __holder_title__ = mo.model["__holder_title__",""]
        if __holder_title__.len > 0{
            displaysHostTitle = false
            displaysWebViewTitle = true
            title = __holder_title__
        }
    }
    
    open func beginRequest()
    {
        webView.load(urlRequest)
    }
    
    
    open override func viewWillAppear(_ animated: Bool) {
        //        assert(navigationController != nil, "\(WebController.self) must be presented in a \(UINavigationController.self)")
        super.viewWillAppear(animated)
        //        self.view.frame = [0,0,Swidth,Sheight]
    }
    
    open override func viewDidDisappear(_ animated: Bool) {
        super.viewDidDisappear(animated)
        webView.stopLoading()
    }
    
    open override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        //
        //        webView.frame = CGRect(
        //            x: view.frame.minX,
        //            y: view.frame.minY,
        //            width: view.frame.size.width,
        //            height: view.frame.size.height)
        
        view.bringSubviewToFront(progressBar)
        progressBar.frame = CGRect(
            x: view.frame.minX,
            y: topLayoutGuide.length,
            width: view.frame.size.width,
            height: 1)
    }
    
    
    // MARK: Actions
    
    @objc internal final func didTapDoneButton(_ sender: UIBarButtonItem) {
        dismiss(animated: true, completion: nil)
    }
    
    @objc internal final func didTapActionButton(_ sender: UIBarButtonItem) {
        if let url = urlRequest.url {
            let activityVC = UIActivityViewController(activityItems: [url], applicationActivities: activities)
            activityVC.popoverPresentationController?.barButtonItem = sender
            present(activityVC, animated: true, completion: nil)
        }
    }
    
    
    open override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
//        print("----kkkkk_",keyPath,object)
        guard let theKeyPath = keyPath , object as? WKWebView == webView else {
            super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
            return
        }
        
        
        if displaysWebViewTitle && theKeyPath == Web.TitleKeyPath {
            title = webView.title
        }
        
        if theKeyPath == Web.EstimatedProgressKeyPath {
            updateProgress()
        }
    }
    
    
    fileprivate func updateProgress() {
        let completed = webView.estimatedProgress >= 1.0
            self.observerProgress(progress: Float(webView.estimatedProgress), commplete: completed)
//            progressBar.setProgress(completed ? 0.0 : Float(webView.estimatedProgress), animated: !completed)
       
        weak var wself = self
        if(completed){
            UIView.animate(withDuration: 0.18, delay: 0.2, options: [.curveEaseInOut]) {
                wself?.progressBar.alpha = 0
            } completion: { (f) in
                wself?.progressBar.alpha = 0
            }        }else{
            UIView.animate(withDuration: 0.18, delay: 0, options: [.curveEaseInOut]) {
                wself?.progressBar.alpha = 1
            } completion: { (f) in
                wself?.progressBar.alpha = 1
            }
        }
        
        progressBar.setProgress(Float(webView.estimatedProgress), animated: true)
               
        UIApplication.shared.isNetworkActivityIndicatorVisible = !completed
    }
    
    open func observerProgress(progress:Float,commplete:Bool)
    {
        
    }
    
    
    
    
}
fileprivate var normalHeight:CGFloat = 1

public class WebProgressView: UIProgressView {
    public override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        super.touchesBegan(touches, with: event)
    }
    public enum Mode {
        case light
        case normal
    }
    
    
//    public override func trackRect(forBounds bounds: CGRect) -> CGRect {
//        var _bounds = bounds
//
//        _bounds.origin.y = _bounds.height - normalHeight;
//        _bounds.size.height = 1;
//        return _bounds
//
//
//        //
//    }
    
    public override func sizeThatFits(_ size: CGSize) -> CGSize {
        let size_ = super.sizeThatFits(size)
 
        return CGSize(width: size_.width, height: normalHeight)
    }
}




extension WebController:WKUIDelegate,WKNavigationDelegate
{
    
    public func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
        let url = navigationAction.request.url
        let scheme = url?.scheme
        if let urlStr = url?.absoluteString{
//            if urlStr.hasPrefix("http://token.firstvar.com"){
//                let token = urlStr.replacingOccurrences(of: "http://token.firstvar.com/get_token#access_token=", with: "")
//                print("token|\(token)")
//                weak var wself = self
//
//                JoTask().get.log_response().log.url("https://api.instagram.com/v1/users/self").params(["access_token":token]).json_handle { (status, msg, obj, resp,tsk) in
//                    if status.isSuccess{
//                        if let dict = obj as? NSMutableDictionary{
//
//                            return
//                        }
//                    }
//                    }.run()
//            }
            
        }
        //        print("====|\(url)===\(url?.pathComponents)")
        
        guard let schemeStr = scheme else {
            decisionHandler(.cancel)
            return
        }
        if schemeStr == "tel" {
            if let u = url
            {
                UIApplication.shared.openURL(u)
            }
        }
        
        if schemeStr == "weixin"
        {
            if let _url = url
            {
                //                print("uuuuuuu++++OOOO|\(scheme)=|\(_url)")
                //                switch  _url.relativePath{
                //                case "/pay":
                if UIApplication.shared.canOpenURL(_url){
                    if #available(iOS 10.0, *) {
                        UIApplication.shared.open(_url, options: [UIApplication.OpenExternalURLOptionsKey.universalLinksOnly : false], completionHandler: nil)
                    } else {
                        UIApplication.shared.openURL(_url)
                        // Fallback on earlier versions
                    }
                }
                
                
                //                default:
                //                    break
                //                }
            }
        }
        decisionHandler(.allow)
    }
    
    
    
    
    public func webView(_ webView: WKWebView, runJavaScriptAlertPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping () -> Void) {
        
        JoAlertView(info: "提示".loc,message).append(title: "确定".loc, action: {
            completionHandler()
        }).alert.show(at: self)
    }
    
    public func webView(_ webView: WKWebView, runJavaScriptConfirmPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping (Bool) -> Void) {
        JoAlertView(info: "提示".loc,message).alert.append(title: "取消".loc, action: {
            debugPrint("canle")
            completionHandler(false)
        }).append(title: "确定".loc, action: {
            debugPrint("confirm")
            completionHandler(true)
        }).show(at: self)
    }
    
    public func webView(_ webView: WKWebView, runJavaScriptTextInputPanelWithPrompt prompt: String, defaultText: String?, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping (String?) -> Void) {
        
    }
}

